#pragma once
#ifndef __G_REF_COUNTER_H__
#define __G_REF_COUNTER_H__

namespace GUtil
{
	// Intrusive referance counter
	// Can only be used with classes inherited fron refcounted
	template <typename T>
	class GRefCounter
	{
	private:
		T* Instance;

	public:
		GRefCounter()
		{
			Instance = NULL;
		}
		
		GRefCounter(const T* Ins)
		{
			Instance = const_cast<T*>(Ins);
			Instance->RefIncrease();
		}
			
		~GRefCounter()
		{
			if (Instance != NULL)
			{
				Instance->RefDecrease();
			}
		}
			
		operator T* ()
		{
			return Instance;
		}

		operator const T* () const
		{
			return Instance;
		}

		operator T& ()
		{
			return *Instance;
		}

		operator const T& () const
		{
			return *Instance;
		}
				
		void Set(const T* Ins)
		{
			if (Instance == Ins)
			{
				return;
			}

			if (Instance != NULL)
			{
				Instance->RefDecrease();
			}

			Instance = const_cast<T*>(Ins);

			if (Instance != NULL)
			{
				Instance->RefIncrease();
			}
		}

		T* Get() const
		{
			return Instance;
		}

		T& operator * () const
		{
			return *Instance;
		}

		const T& operator * () const
		{
			return *Instance;
		}

		T* operator -> () const
		{
			return Instance;
		}

		const T* operator -> () const
		{
			return Instance;
		}

		const GRefCounter<T>& operator = (const T* Ins)
		{
			Set(Ins);

			return *this;
		}

		const GRefCounter<T>& operator = (const GRefCounter<T>& Other)
		{
			Set (Other.Instance);

			return *this;
		}
	
	};

}

#endif